package com.siyoumi.app.sys.service.wxapi;

import com.siyoumi.app.sys.service.WxTokenService;
import com.siyoumi.entity.SysAccsuperConfig;
import com.siyoumi.exception.EnumSys;
import com.siyoumi.exception.XException;
import com.siyoumi.util.*;
import com.siyoumi.component.XApp;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

@Slf4j
public class ApiBase {
    static private final String baseApiRoot = "https://api.weixin.qq.com/";

    @Getter
    private ApiConfig config;

    public void setConfig(SysAccsuperConfig entityConfig) {
        ApiConfig apiConfig = new ApiConfig();
        apiConfig.setAppId(entityConfig.getAconfig_app_id());
        apiConfig.setAppSecret(entityConfig.getAconfig_app_secret());

        //获取token
        String accountToken = WxTokenService.getBean(entityConfig).getAccessToken();
        apiConfig.setAccessToken(accountToken);

        apiConfig.setPayAppId(entityConfig.getAconfig_pay_app_id());
        apiConfig.setMchId(entityConfig.getAconfig_partnerId());
        apiConfig.setMchKey(entityConfig.getAconfig_partnerKey());
        if (XStr.hasAnyText(entityConfig.getAconfig_partnerId_sub())) {
            apiConfig.setMchIdSub(entityConfig.getAconfig_partnerId_sub());
        }

        this.config = apiConfig;
    }

    public void setConfig(ApiConfig config) {
        this.config = config;
    }

    /**
     * 获取接口URL
     */
    protected String getApiUrl(String urlFix, String accessToken) {
        String url = XStr.concat(baseApiRoot, urlFix);
        if (XStr.hasAnyText(accessToken)) {
            url = XStr.concat(url, "?access_token=", accessToken);
        }

        return url;
    }

    protected String getApiUrl(String urlFix) {
        return getApiUrl(urlFix, null);
    }

    /**
     * 接口调用
     */
    protected XReturn api(String url, String method, Map<String, Object> data) {
        log.debug(url);
        log.debug(method);
        log.debug(XJson.toJSONString(data));

        XReturn r = EnumSys.API_ERROR.getR();
        try {
            XHttpClient client = XHttpClient.getInstance();
            String returnStr;
            if (XHttpClient.METHOD_GET.equals(method)) {
                //get请求
                returnStr = client.get(url, null);
            } else {
                //post请求
                returnStr = client.postJson(url, null, data);
            }

            r = XReturn.parse(returnStr);
        } catch (Exception ex) {
            r.setErrMsg(ex.getMessage());
        }
        log.debug(XJson.toJSONString(r));

        return r;
    }

    protected XReturn api(String url) {
        return api(url, XHttpClient.METHOD_GET, null);
    }


    /**
     * 获取access_token
     */
    public XReturn getAccessToken() {
        String apiUrl = getApiUrl("cgi-bin/token");

        HashMap<String, String> data = new HashMap<>();
        data.put("appid", getConfig().getAppId());
        data.put("secret", getConfig().getAppSecret());
        data.put("grant_type", "client_credential");
        String query = XStr.queryFromMap(data, null, false);
        String url = XStr.concat(apiUrl, "?", query);

        return api(url);
    }


    /**
     * 生成假openid
     * 总长度29位
     *
     * @param prefix 前缀长度6位，例：oGpYb0
     * @param num
     */
    static public String getOpenidFalse(String prefix, Integer num) {
        if (prefix.length() < 6) {
            throw new XException("prefix min 6");
        }
        prefix = XStr.maxLen(prefix, 6);

        String[] idXArr = "abcdefijkh".split("");

        String id = XApp.getStrID() + num;
        String[] idArr = id.split("");

        StringBuilder sb = new StringBuilder();
        for (String s : idArr) {
            String sNew = s;
            Boolean change = XApp.random(0, 100) > 30; // 换英文
            if (change) {
                sNew = idXArr[Integer.valueOf(s)];
                Boolean upperCase = XApp.random(0, 100) > 50; // 大写
                if (upperCase) {
                    sNew = sNew.toUpperCase();
                }
            }

            sb.append(sNew);
        }

        String idNew = prefix + sb.toString();
        log.info("id: {}", id);
        log.info("id_new: {}", idNew);

        return idNew;
    }
}
